<template>
	<view class="my-swiper" :class="{ vertical: isVertical }" :style="containerStyle">
		<swiper class="swiper" v-bind="swiperConfig" @change="handleChange" @animationfinish="handleAnimationFinish">
			<swiper-item v-for="(item, index) in list" :key="index" @click="handleItemClick(item)" class="swiper-item"
				:style="itemStyle">
				<view class="swiper-content" :style="contentStyle">
					<view class="image-container" :style="imageContainerStyle">
						<image :src="item.image" :mode="options.imageMode" class="swiper-image" :style="imageStyle"
							@load="handleImageLoad(index)" @error="handleImageError(index)" :show-loading="true"
							:show-menu-by-longpress="true" />
						<view v-if="options.showOverlay" class="image-overlay" :style="overlayStyle"></view>
					</view>

					<view v-if="options.showTitle && item.title" class="title-container" :style="titleStyle">
						<view class="title-text">{{ item.title }}</view>
						<view v-if="item.subtitle" class="subtitle-text">{{ item.subtitle }}</view>
					</view>
				</view>
			</swiper-item>
		</swiper>

		<view v-if="options.customIndicator" class="custom-indicator" :style="indicatorStyle">
			<view v-for="(_, index) in list" :key="index" class="indicator-dot"
				:class="{ active: currentIndex === index }" :style="getIndicatorDotStyle(index)"></view>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'my-swiper',
		props: {
			list: {
				type: Array,
				default: () => []
			},
			options: {
				type: Object,
				default: () => ({})
			},
			height: {
				type: [String, Number],
				default: '400rpx'
			},
			width: {
				type: [String, Number],
				default: '100%'
			},
			radius: {
				type: [String, Number],
				default: '0'
			}
		},
		data() {
			return {
				currentIndex: 0,
				defaultOptions: {
					indicatorDots: true,
					indicatorColor: 'rgba(255, 255, 255, 0.6)',
					indicatorActiveColor: '#ffffff',
					autoplay: true,
					interval: 3000,
					duration: 500,
					circular: true,
					vertical: false,
					previousMargin: '0px',
					nextMargin: '0px',
					acceleration: false,
					disableTouch: false,
					displayMultipleItems: 1,
					imageMode: 'aspectFill',
					customIndicator: false,
					indicatorPosition: 'bottom',
					indicatorStyle: {},
					showTitle: false,
					titlePosition: 'bottom',
					titleStyle: {},
					showOverlay: false,
					overlayColor: 'rgba(0, 0, 0, 0.3)',
					overlayGradient: false,
					imageFit: 'cover',
					imageRadius: '12rpx',
					shadowEffect: false,
					cardEffect: false,
					scale: false,
					scaleRatio: 0.9,
					animationMode: 'default',
					animationDuration: 500,
					verticalOptions: {
						enabled: false,
						height: '400rpx',
						spacing: '20rpx'
					}
				}
			}
		},
		computed: {
			mergedOptions() {
				return {
					...this.defaultOptions,
					...this.options
				}
			},
			containerStyle() {
				return {
					height: typeof this.height === 'number' ? `${this.height}rpx` : this.height,
					width: typeof this.width === 'number' ? `${this.width}rpx` : this.width
				}
			},
			imageStyle() {
				return {
					borderRadius: typeof this.radius === 'number' ? `${this.radius}rpx` : this.radius
				}
			},
			itemStyle() {
				return {
					padding: this.mergedOptions.itemPadding || '0'
				}
			},
			contentStyle() {
				const {
					cardEffect,
					shadowEffect
				} = this.mergedOptions
				return {
					borderRadius: this.mergedOptions.imageRadius,
					boxShadow: shadowEffect ? '0 4rpx 12rpx rgba(0, 0, 0, 0.15)' : 'none',
					transform: cardEffect ? 'scale(0.9)' : 'none',
					transition: 'all 0.3s'
				}
			},
			overlayStyle() {
				const {
					overlayColor,
					overlayGradient
				} = this.mergedOptions
				return {
					background: overlayGradient ?
						'linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.7))' :
						overlayColor
				}
			},
			titleStyle() {
				const {
					titlePosition,
					titleStyle
				} = this.mergedOptions
				return {
					position: titlePosition === 'overlay' ? 'absolute' : 'relative',
					bottom: titlePosition === 'overlay' ? '0' : 'auto',
					...titleStyle
				}
			},
			indicatorStyle() {
				const {
					indicatorPosition,
					indicatorStyle
				} = this.mergedOptions
				const positionStyles = {
					bottom: {
						bottom: '20rpx',
						left: '50%',
						transform: 'translateX(-50%)'
					},
					bottomLeft: {
						bottom: '20rpx',
						left: '20rpx'
					},
					bottomRight: {
						bottom: '20rpx',
						right: '20rpx'
					}
				}
				return {
					...positionStyles[indicatorPosition],
					...indicatorStyle
				}
			},
			imageContainerStyle() {
				const { imageFit } = this.mergedOptions
				return {
					overflow: 'hidden',
					position: 'relative',
					display: 'flex',
					justifyContent: 'center',
					alignItems: 'center'
				}
			},
			isVertical() {
				return this.mergedOptions.verticalOptions?.enabled
			},
			swiperConfig() {
				const options = { ...this.mergedOptions }
				if (this.isVertical) {
					options.vertical = true
					options.previousMargin = options.verticalOptions.spacing
					options.nextMargin = options.verticalOptions.spacing
				}
				const {
					verticalOptions,
					customIndicator,
					showTitle,
					titlePosition,
					showOverlay,
					overlayGradient,
					cardEffect,
					shadowEffect,
					titleStyle,
					...swiperProps
				} = options
				return swiperProps
			}
		},
		methods: {
			handleChange(e) {
				this.currentIndex = e.detail.current
				this.$emit('change', e.detail.current)
			},
			handleItemClick(item) {
				this.$emit('click', item)
			},
			handleAnimationFinish(e) {
				this.$emit('animationfinish', e.detail)
			},
			handleImageLoad(index) {
				this.$emit('imageload', index)
			},
			handleImageError(index) {
				console.error(`Image load failed at index ${index}`)
				this.$emit('error', { index, image: this.list[index].image })
			},
			getIndicatorDotStyle(index) {
				const isActive = this.currentIndex === index
				return {
					transform: isActive ? 'scale(1.2)' : 'scale(1)',
					opacity: isActive ? 1 : 0.6
				}
			}
		}
	}
</script>

<style lang="scss" scoped>
	.my-swiper {
		width: 100%;
		position: relative;

		.swiper {
			width: 100%;
			height: 100%;
		}

		.swiper-item {
			display: flex;
			justify-content: center;
			align-items: center;
			overflow: hidden;
		}

		.swiper-content {
			width: 100%;
			height: 100%;
			position: relative;
			overflow: hidden;
		}

		.image-container {
			width: 100%;
			height: 100%;
			position: relative;
		}

		.swiper-image {
			width: 100%;
			height: 100%;
		}

		.image-overlay {
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			pointer-events: none;
		}

		.title-container {
			padding: 30rpx;
			color: #fff;
			z-index: 1;

			.title-text {
				font-size: 32rpx;
				font-weight: bold;
				line-height: 1.4;
				margin-bottom: 10rpx;
			}

			.subtitle-text {
				font-size: 24rpx;
				opacity: 0.8;
				margin-top: 8rpx;
				display: -webkit-box;
				-webkit-box-orient: vertical;
				-webkit-line-clamp: 2;
				overflow: hidden;
				text-overflow: ellipsis;
			}
		}

		.custom-indicator {
			position: absolute;
			display: flex;
			margin-right: 30rpx;
			margin-bottom: 10rpx;
			gap: 12rpx;
			z-index: 2;

			.indicator-dot {
				width: 12rpx;
				height: 12rpx;
				border-radius: 50%;
				background-color: #fff;
				transition: all 0.3s;

				&.active {
					width: 24rpx;
					border-radius: 6rpx;
				}
			}
		}

		.fade-enter-active,
		.fade-leave-active {
			transition: opacity 0.5s;
		}
		
		.fade-enter,
		.fade-leave-to {
			opacity: 0;
		}

		.flip-enter-active,
		.flip-leave-active {
			transition: transform 0.5s;
		}
		
		.flip-enter,
		.flip-leave-to {
			transform: rotateY(180deg);
		}

		.cube-enter-active,
		.cube-leave-active {
			transition: transform 0.5s;
			transform-style: preserve-3d;
		}
		
		.cube-enter,
		.cube-leave-to {
			transform: rotateY(-90deg);
		}

		.zoom-enter-active,
		.zoom-leave-active {
			transition: transform 0.5s, opacity 0.5s;
		}
		
		.zoom-enter,
		.zoom-leave-to {
			transform: scale(0.3);
			opacity: 0;
		}

		&.vertical {
			.swiper {
				height: v-bind('mergedOptions.verticalOptions.height') !important;

				.swiper-item {
					width: 100% !important;
					height: 100% !important;
				}

				.swiper-content {
					position: relative;
					height: 100%;
				}

				.image-container {
					width: 100%;
					height: 100%;
				}

				.swiper-image {
					width: 100%;
					height: 100%;
					object-fit: cover;
				}
			}

			.custom-indicator {
				flex-direction: column;
				right: 10rpx;
				top: 50%;
				transform: translateY(-50%);
				margin: 0 !important;
				z-index: 3;
				position: absolute;
				margin-right: 10rpx !important;
				
				.indicator-dot {
					margin: 4rpx 0;
					width: 8rpx;
					height: 8rpx;
					
					&.active {
						width: 8rpx;
						height: 16rpx;
						border-radius: 4rpx;
					}
				}
			}

			.title-container {
				position: absolute;
				bottom: 0;
				left: 0;
				width: 100%;
				z-index: 2;
			}

			.image-overlay {
				z-index: 1;
			}
		}
	}
</style>